﻿using System.Collections.Generic;


//小红点只有叶子才会有消息
namespace UFrame
{
    public sealed class SysMsgMgr : Singleton<SysMsgMgr>
    {
        private SysMsgMgr() { Init(); }

        //标准UI树形结构
        private Dictionary<ESysRedType, TreeStruct<SysMsgNode>> mDicMsg = new Dictionary<ESysRedType, TreeStruct<SysMsgNode>>();

        //优化搜索的结构,快速找到每一个节点进行操作
        private Dictionary<ESysRedType, TreeStruct<SysMsgNode>> mDicMsgTemp = new Dictionary<ESysRedType, TreeStruct<SysMsgNode>>();


        private List<SysMsgReciever> mListReceivers = new List<SysMsgReciever>();

        private bool mbInited = false;

        private void Init()
        {
            if (mbInited)
            {
                return;
            }

            InitTree(ESysRedType.None, ESysRedType.BagLv1);
            InitTree(ESysRedType.BagLv1, ESysRedType.BagForgeLv2);
            InitTree(ESysRedType.BagLv1, ESysRedType.BagStarLv2);
            InitTree(ESysRedType.BagStarLv2, ESysRedType.BagStarLv3);
            InitTree(ESysRedType.BagForgeLv2, ESysRedType.BagForgeLv3);

            mbInited = true;
        }

        public void Notify(ESysRedType type, SysMsg sm)
        {
            TreeStruct<SysMsgNode> root = null;
            if (mDicMsg.ContainsKey(type))
            {
                root = mDicMsg[type];
                OperationTreeChild(root, sm, true);
            }

            for (int i = 0; i < mListReceivers.Count; i++)
            {
                mListReceivers[i].Notify(sm.mType, true);
            }
            root = null;
        }

        public bool HasNew(ESysRedType type, string guid)
        {
            var node = mDicMsgTemp[type];

            bool result = false;
            if (node.IsChildrenNull())      //是否叶子节点
            {
                if (string.IsNullOrEmpty(guid))
                {
                    result = node.Value.MsgCount() > 0;
                }
                else
                {
                    result = node.Value.HasMsg(guid);
                }
            }
            else
            {
                List<TreeStruct<SysMsgNode>> list = new List<TreeStruct<SysMsgNode>>();
                int index = 0;
                list.AddRange(node.Children);

                while (list.Count > 0)
                {
                    var treeNode = list[index];
                    list.RemoveAt(index);
                    index = 0;

                    if (treeNode.IsChildrenNull())
                    {
                        if (string.IsNullOrEmpty(guid))
                        {
                            result = treeNode.Value.MsgCount() > 0;
                        }
                        else
                        {
                            result = node.Value.HasMsg(guid);
                        }

                        break;
                    }
                    else
                    {
                        list.AddRange(treeNode.Children);
                    }
                }
            }

            return result;
        }

        public bool RemoveMsg(ESysRedType type, string guid = null, bool isNotify = true)
        {
            //guid = null 决定整体删除
            var node = mDicMsgTemp[type];

            bool result = false;
            if (node.IsChildrenNull())      //是否叶子节点
            {
                result = node.Value.MsgCount() == 0;
            }
            else
            {
                List<TreeStruct<SysMsgNode>> list = new List<TreeStruct<SysMsgNode>>();
                int index = 0;

                if (string.IsNullOrEmpty(guid))
                {
                    list.Add(node);
                }
                else
                {
                    list.AddRange(node.Children);
                }

                while (list.Count > 0)
                {
                    var treeNode = list[index];
                    list.RemoveAt(index);
                    index = 0;

                    if (string.IsNullOrEmpty(guid))
                    {
                        treeNode.Value.RemoveAllMsg();
                        result = true;
                    }
                    else if (treeNode.IsChildrenNull())
                    {
                        result = treeNode.Value.HasMsg(guid);
                        treeNode.Value.RemoveMsg(guid);
                        break;
                    }

                    list.AddRange(treeNode.Children);
                }
            }

            if (result && isNotify)
            {
                SysMsgReciever sr = null;
                for (int i = 0; i < mListReceivers.Count; i++)
                {
                    sr = mListReceivers[i];
                    if (string.IsNullOrEmpty(guid))             //通知全部子节点的红点不显示,
                    {
                        for (int z = 0; z < sr.ListType.Count; z++)
                        {
                            if (IsParent(type, sr.ListType[z]))
                            {
                                sr.Notify(false);
                                break;
                            }
                            else if (sr.ListType[z] == node.Parent.Value.mType)
                            {
                                sr.Refresh(sr.ListType[z]);
                                break;
                            }
                        }
                    }
                    else
                    {
                        sr.Notify(type, false);
                    }
                }
            }
            return result;
        }

        public void AddReciever(SysMsgReciever rec)
        {
            if (!mListReceivers.Contains(rec))
            {
                mListReceivers.Add(rec);
            }
        }

        public void RemoveReceiver(SysMsgReciever rec)
        {
            if (mListReceivers.Contains(rec))
            {
                mListReceivers.Remove(rec);
            }
        }

        public void OperationTreeChild(TreeStruct<SysMsgNode> tree, SysMsg msg, bool add)
        {
            if (tree.Value.mType == msg.mType)
            {
                tree.Value.AddSysMsg(msg);
            }
            else
            {
                if (tree.Children == null)
                {
                    PLDebug.LogError("未找到节点: " + msg.mType);
                    return;
                }

                TreeStruct<SysMsgNode> node = null;
                List<TreeStruct<SysMsgNode>> list = new List<TreeStruct<SysMsgNode>>();
                list.AddRange(tree.Children);

                int index = 0;
                while (list.Count > 0)
                {
                    node = list[index];
                    list.RemoveAt(index);
                    index = 0;

                    //PLDebug.Log("遍历节点:" + node.Value.mType);
                    if (node.Value.mType == msg.mType)
                    {
                        if (add)
                        {
                            node.Value.AddSysMsg(msg);
                        }
                        else
                        {
                            node.Value.RemoveMsg(msg);
                        }

                        break;
                    }
                    else
                    {
                        list.AddRange(node.Children);
                    }
                }
            }
        }


        public bool IsParent(ESysRedType parent, ESysRedType child)
        {
            var tree = mDicMsgTemp[child];

            TreeStruct<SysMsgNode> p = null;
            p = tree.Parent;
            bool result = false;

            if (tree.Value.mType == parent)
            {
                result = true;
            }
            else
            {
                while (p != null)
                {
                    if (p.Value.mType == parent)
                    {
                        result = true;
                        break;
                    }

                    p = p.Parent;
                }
            }

            return result;
        }

        private void InitTree(ESysRedType parent, ESysRedType child)
        {
            TreeStruct<SysMsgNode> node = null;

            if (parent == ESysRedType.None)
            {
                node = new TreeStruct<SysMsgNode>();
                node.Value = new SysMsgNode();
                node.Value.mType = child;

                mDicMsg.Add(child, node);
                mDicMsgTemp.Add(child, node);
            }
            else
            {
                if (mDicMsgTemp.ContainsKey(parent))
                {
                    node = mDicMsgTemp[parent];
                    TreeStruct<SysMsgNode> n = new TreeStruct<SysMsgNode>();
                    n.Value = new SysMsgNode();
                    n.Value.mType = child;
                    node.AddChild(n);
                    mDicMsgTemp.Add(child, n);
                }
                else
                {
                    PLDebug.LogError("不包含:" + parent);
                }


            }
        }



    }

    public enum ESysRedType     //每一个系统的标记,Lv越高代表层级越深(因为编辑器所以不要中间插入)
    {
        None = 1,
        BagLv1 = 2,
        BagForgeLv2 = 3,
        BagForgeLv3 = 4,
        BagStarLv2 = 5,
        BagStarLv3 = 6,
    }

    public class SysMsgNode         //界面上UI小红点的树形结构
    {
        public ESysRedType mType = ESysRedType.None;
        private List<SysMsg> mMsgList;


        public int MsgCount()
        {
            if (mMsgList == null || mMsgList.Count == 0)
            {
                return 0;
            }

            return mMsgList.Count;
        }

        public void AddSysMsg(SysMsg msg)
        {
            if (mMsgList == null)
            {
                mMsgList = new List<SysMsg>();
            }

            mMsgList.Add(msg);
        }

        public bool HasMsg(SysMsg msg)
        {
            return HasMsg(msg.guid);
        }

        public bool HasMsg(string guid)
        {
            if (mMsgList == null)
            {
                return false;
            }

            for (int i = 0; i < mMsgList.Count; i++)
            {
                if (mMsgList[i].guid == guid)
                {
                    return true;
                }
            }
            return false;
        }

        public void RemoveMsg(SysMsg msg)
        {
            RemoveMsg(msg.guid);
        }

        public void RemoveMsg(string guid)
        {
            if (mMsgList == null)
            {
                return;
            }

            for (int i = 0; i < mMsgList.Count; i++)
            {
                if (mMsgList[i].guid == guid)
                {
                    mMsgList.RemoveAt(i);
                    break;
                }
            }
        }

        public void RemoveAllMsg()
        {
            if (mMsgList == null)
            {
                return;
            }

            mMsgList.Clear();
        }
    }

    public class SysMsg         //系统信息
    {
        public ESysRedType mType = ESysRedType.None;
        public string guid = string.Empty;
    }

}